// Copyright (C) 2025 Kumo inc.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//

#if !defined( __cpp_exceptions )
#include <iostream>
int main()
{
   std::cout << "Exception support disabled, skipping test..." << std::endl;
}
#else

#include "test.hpp"

#include "verify_meta.hpp"

namespace rothar
{
   template< tracking_mode M >
   void unit_test()
   {
      const std::string rulename{ demangle< digit >() };

      memory_input< M > in( "foo\nbar bla blubb\nbaz", "test_source" );

      try {
         parse< seq< identifier, eol, identifier, one< ' ' >, must< digit > > >( in );
      }
      catch( const parse_error& e ) {
         ROTHAR_PEGTL_TEST_ASSERT( e.what() == "test_source:2:5: parse error matching " + rulename );

         ROTHAR_PEGTL_TEST_ASSERT( e.message() == "parse error matching " + rulename );

         ROTHAR_PEGTL_TEST_ASSERT( e.positions().size() == 1 );
         const auto& p = e.positions().front();

         ROTHAR_PEGTL_TEST_ASSERT( p.byte == 8 );
         ROTHAR_PEGTL_TEST_ASSERT( p.line == 2 );
         ROTHAR_PEGTL_TEST_ASSERT( p.column == 5 );
         ROTHAR_PEGTL_TEST_ASSERT( p.source == "test_source" );

         ROTHAR_PEGTL_TEST_ASSERT( in.line_at( p ) == "bar bla blubb" );

         position p2 = p;
         p2.source = "foo";
         p2.line = 42;
         p2.column = 123;

         parse_error e2 = e;
         e2.add_position( std::move( p2 ) );

         ROTHAR_PEGTL_TEST_ASSERT( e2.what() == "foo:42:123: test_source:2:5: parse error matching " + rulename );
         ROTHAR_PEGTL_TEST_ASSERT( e.what() == "test_source:2:5: parse error matching " + rulename );

         return;
      }
      ROTHAR_PEGTL_TEST_UNREACHABLE;  // LCOV_EXCL_LINE
   }

   void unit_test()
   {
      unit_test< tracking_mode::eager >();
      unit_test< tracking_mode::lazy >();
   }

}  // namespace rothar

#include "main.hpp"

#endif
